package com.cwz.auth.service;

import com.cwz.api.entity.SysUser;
import com.cwz.core.constant.CacheConstants;
import com.cwz.core.constant.Constants;
import com.cwz.core.exception.service.ServiceException;
import com.cwz.core.utils.string.StringUtils;
import com.cwz.redis.service.RedisService;
import com.cwz.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @program: w-demo
 * @description: 登录密码方法
 * @author: Wen
 **/
@Service
public class SysPasswordService {
	@Autowired
	private RedisService redisService;
	@Autowired
	private SysRecordLogService sysRecordLogService;
	/**
	 * 密码最大错误次数
	 */
	private int maxRetryCount = CacheConstants.PASSWORD_MAX_RETRY_COUNT;
	/**
	 * 密码锁定时间，默认10（分钟）
	 */
	private Long lockTime = CacheConstants.PASSWORD_LOCK_TIME;

	/**
	 * @Description: 验证密码
	 * @Author: Wen
	 * @param sysUser:		用户信息
	 * @param password:		输入的密码
	 * @return: void
	 **/
	public void validate(SysUser sysUser, String password) {
		String userName = sysUser.getUserName();
		Integer retryCount = this.redisService.getCacheObject(getCacheKey(userName));
		if (StringUtils.isNull(retryCount)) {
			retryCount = 0;
		}
		if (retryCount >= maxRetryCount) {
			String errMsg = String.format("密码输入错误 %s 次，帐户锁定 %s 分钟", maxRetryCount, lockTime);
			this.sysRecordLogService.recordLogininfor(userName, Constants.LOGIN_FAIL, errMsg);
			throw new ServiceException(errMsg);
		}
		if (!matches(sysUser, password)) {
			retryCount = retryCount + 1;
			this.sysRecordLogService.recordLogininfor(userName, Constants.LOGIN_FAIL, String.format("密码输入错误 %s 次", retryCount));
			this.redisService.setCacheObject(getCacheKey(userName), retryCount, lockTime, TimeUnit.MINUTES);
			throw new ServiceException("用户不存在/密码错误");
		} else {
			clearLoginRecordCache(userName);
		}
	}

	/**
	 * @Description: 登录账户密码错误次数缓存键名
	 * @Author: Wen
	 * @param username:	用户名
	 * @return: java.lang.String
	 **/
	private String getCacheKey(String username) {
		return CacheConstants.PWD_ERR_CNT_KEY + username;
	}

	/**
	 * @Description: 比较密码
	 * @Author: Wen
	 * @param sysUser: 		用户信息
	 * @param rawPassword:  输入的密码
	 * @return: boolean
	 **/
	private boolean matches(SysUser sysUser, String rawPassword) {
		return SecurityUtils.matchesPassword(rawPassword, sysUser.getPassword());
	}

	/**
	 * @Description: 清楚登录账户密码错误次数缓存
	 * @Author: Wen
	 * @param username:  用户名
	 * @return: void
	 **/
	private void clearLoginRecordCache(String username) {
		if (this.redisService.hasKey(getCacheKey(username))) {
			this.redisService.deleteObject(getCacheKey(username));
		}
	}
}
